package org.fxcontainer.actions
{
	import com.developmentarc.core.actions.actions.AbstractAction;
	
	import flash.events.Event;
	
	import mx.core.UIComponent;
	import mx.events.FlexEvent;
	
	import org.as3commons.logging.ILogger;
	import org.as3commons.logging.LoggerFactory;
	import org.fxcontainer.commands.ControlInvocationCommand;
	import org.fxcontainer.controls.IControl;
	import org.fxcontainer.registry.ControlRegistry;
	import org.fxcontainer.registry.PageRegistry;
	import org.fxcontainer.structure.IPage;
	import org.fxcontainer.utils.ControlInvokeHelper;
	
	/**
	 * Invokes control command action handler. 
	 * @author Izzet_Mustafayev
	 */
	public class ControlInvocationAction extends AbstractAction
	{
		/**
		 * The command reference. 
		 */
		private var command:ControlInvocationCommand;
		
		/**
		 * The logger reference. 
		 */
		static private var logger:ILogger = LoggerFactory.getClassLogger(ControlInvocationAction);
		
		/**
		 * The control invocation action constructor.
		 */
		public function ControlInvocationAction()
		{
			super();
			//register applyable command
			this.addCommand(ControlInvocationCommand.CTRL_INVOKE_CMD);
		}
		
		/**
		 * Process command invocation.  
		 * @param command the command to apply for invocation
		 */
		override public function applyAction(_command:Event):void
		{
			if (null != _command && _command is ControlInvocationCommand){
				this.command = _command as ControlInvocationCommand;
				logger.debug("Enter to control \"{0}\" on page \"{1}\" invocation state.", this.command.controlName, this.command.pageName);
				var page:IPage = PageRegistry.getPage(this.command.pageName);
				if (null != page){
					var pageComponent:UIComponent = UIComponent(page);
					//check whether page was initialized to invoke control
					if (!pageComponent.initialized){
						pageComponent.addEventListener(FlexEvent.CREATION_COMPLETE, delayControlInvocation);
					}
					//if page is initialized we can invoke control
					if (pageComponent.initialized){
						invokeControl();
					}
				}
			}
		}
		
		/**
		 * Delays control invocation due to control unavailability on a page. 
		 * @param event the event indicates that page was initialized
		 */
		private function delayControlInvocation(event:FlexEvent):void
		{
			if (null != event){
				invokeControl();
			}
		}
		
		/**
		 * Invokes control.
		 */
		private function invokeControl():void
		{
			var page:IPage = PageRegistry.getPage(this.command.pageName);
			var control:IControl = ControlRegistry.getControl(this.command.pageName, this.command.controlName);
			if (null != control){
				logger.debug("Invoke control {0} method {1}.", this.command.controlName, this.command.methodName);
				ControlInvokeHelper.execute(control, this.command.methodName, this.command.methodArgs);
			}
			if (null == control){
				logger.error("Control \"{0}\" was not found on a page or is not initialized yet.", command.controlName);
			}
		}
	}
}